import {
  Mark,
  markInputRule,
  markPasteRule,
  mergeAttributes,
} from "@tiptap/core";

export interface wavyOptions {
  HTMLAttributes: Record<string, any>;
}

declare module "@tiptap/core" {
  interface Commands<ReturnType> {
    wavy: {
      /**
       * Set a bold mark
       */
      setWavy: () => ReturnType;
      /**
       * Toggle a bold mark
       */
      toggleWavy: () => ReturnType;
      /**
       * Unset a bold mark
       */
      unsetWavy: () => ReturnType;
    };
  }
}

export const starInputRegex = /(?:^|\s)((?:\*\*)((?:[^*]+))(?:\*\*))$/;
export const starPasteRegex = /(?:^|\s)((?:\*\*)((?:[^*]+))(?:\*\*))/g;
export const underscoreInputRegex = /(?:^|\s)((?:__)((?:[^__]+))(?:__))$/;
export const underscorePasteRegex = /(?:^|\s)((?:__)((?:[^__]+))(?:__))/g;

export const Wavy = Mark.create<wavyOptions>({
  name: "wavy",

  addOptions() {
    return {
      HTMLAttributes: {
        style: `text-decoration: underline;
        text-decoration-style: wavy;`,
      },
    };
  },

  // 反显的时候匹配用 https://tiptap.dev/guide/custom-extensions/#parse-html
  parseHTML() {
    return [
      {
        tag: "wavy",
      },
    ];
  },

  // 控制扩展如何呈现为 HTML
  renderHTML({ HTMLAttributes }) {
    return [
      "wavy",
      mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
      0,
    ];
  },

  addCommands() {
    return {
      setWavy: () => ({ commands }) => {
        return commands.setMark(this.name);
      },
      toggleWavy: () => ({ commands }) => {
        return commands.toggleMark(this.name);
      },
      unsetWavy: () => ({ commands }) => {
        return commands.unsetMark(this.name);
      },
    };
  },

  addInputRules() {
    return [
      markInputRule({
        find: starInputRegex,
        type: this.type,
      }),
      markInputRule({
        find: underscoreInputRegex,
        type: this.type,
      }),
    ];
  },

  addPasteRules() {
    return [
      markPasteRule({
        find: starPasteRegex,
        type: this.type,
      }),
      markPasteRule({
        find: underscorePasteRegex,
        type: this.type,
      }),
    ];
  },
});
